Thread: Trying out fork exec pipe on a simple "ls | cat" but get no output

  1. #1
    Registered User
    Join Date
    Oct 2009
    Posts
    7

    Trying out fork exec pipe on a simple "ls | cat" but get no output

    So all I want this program to do is if i typed in
    Code:
    ls | cat
    I know i dont even need the cat, i'm just trying to learn the pipe part of this also.
    Code:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
    
    void sighandler(int id)
    {
        printf("Got a signal\n");
    }
    
    int main(int argc, char *argv[])
    {
        /* do a ls | cat */
        char *ls = "ls";
        char *cat = "cat";
        char *lsargs[] = {"ls"};
        char *catargs[] = {"cat"};
    
        struct sigaction asignal;
        sigemptyset(&asignal.sa_mask);
        asignal.sa_handler = sighandler;
        asignal.sa_flags = 0;
        sigaction(SIGCHLD, &asignal, (struct sigaction *) NULL);
    
        int status;
        int pid = fork();
        if(pid > 0)
        {
            /* parent waits for SIGCHLD */
            waitpid(-1, &status, 0);
            printf("children finished\n");
        }
        if(pid == 0)
        {
            /* this should spawn an ls. redirect output to cat */
            int fd[2];
            pipe(fd);
            int cid = fork();
            if(cid > 0)
            {
                /* this is the ls */
                close(fd[0]);           /* close read pipe */
                close(STDOUT_FILENO);   /* close standard out */
                dup(fd[1]);             /* make write pipe stand ard out */
                close(fd[1]);           /* close my ptr to write pipe */
                execve(ls, lsargs, 0);
                exit(0);
            }
            else
            {
                /* this is the cat */
                close(fd[1]);           /* close write pipe */
                close(STDIN_FILENO);    /* close standard in */
                dup(fd[0]);             /* make read pipe standard in */
                close(fd[0]);           /* close my ptr to read pipe */
                execve(cat, catargs, 0);
                exit(0);
            }
        }
        printf("completed.\n");
    }
    When i run this i'm assuming it works fine in the background, but i get no output except for the printfs() in the parent process. Is there something im doing wrong here that is preventing me from seeing output? All open FD's get closed so nothing is hanging.

    Parent process stdin and stdout are untouched.
    Child 1 is made.
    Child 2 is made.
    ---
    After this child 1 and child2's stdout and stdin are messed with for piping. So child 2 should be printing to standard out.
    Last edited by foolfoolz; 10-14-2009 at 02:01 PM.

  2. #2
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    That's because you are fork()'ng twice. What do you need the second fork() for??

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by itCbitC View Post
    That's because you are fork()'ng twice. What do you need the second fork() for??
    You need to fork() twice if you are launching two processes. Otherwise the main process would get replaced by one of them.

    I don't immediately see what's wrong with this code.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    I think your problem is the usage of execve(). The argument lists need to be terminated by a NULL pointer. Try changing this:

    Quote Originally Posted by foolfoolz View Post
    Code:
        char *lsargs[] = {"ls"};
        char *catargs[] = {"cat"};
    To this:

    Code:
        char *lsargs[] = {"ls", NULL };
        char *catargs[] = {"cat", NULL };
    Everything else seems fine.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  5. #5
    Registered User
    Join Date
    Oct 2009
    Posts
    7
    yea i thought since a stirng in "quotes" is automatically terminated by null character, then an array of strings with only 1 string would end at that null.

    works good

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Base converter libary
    By cdonlan in forum C++ Programming
    Replies: 22
    Last Post: 05-15-2005, 01:11 AM
  2. exec and buffered output
    By optimus in forum C Programming
    Replies: 5
    Last Post: 04-26-2004, 03:25 AM
  3. File Input and Output, simple.
    By Vber in forum C Programming
    Replies: 5
    Last Post: 11-17-2002, 02:57 PM
  4. Simple question on quoting output
    By LouB in forum C++ Programming
    Replies: 13
    Last Post: 06-16-2002, 02:57 PM
  5. Simple File Creation Algorithm
    By muffin in forum C Programming
    Replies: 13
    Last Post: 08-24-2001, 03:28 PM